package com.bzkj.document.utils.transferorder;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.bzkj.common.domain.NccApiResponse;
import com.bzkj.common.domain.NccRequestDTO;
import com.bzkj.common.mapper.SelectInfoMapper;
import com.bzkj.document.mapper.WhstransbillMapper;
import com.bzkj.document.mapper.WmsWareHouseInventoryMapper;
import com.bzkj.document.utils.common.DataProcessUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @projectName: prt-wms
 * @package: com.bzkj.document.utils.transferorder
 * @className: TransferOrderUtils
 * @description: 转库单处理模块
 * @author: C1309
 * @createDate: 2025年01月06日
 * @version: v1.0
 */
@Component
public class TransferOrderUtils {
    @Resource
    private WhstransbillMapper whstransbillMapper;

    @Resource
    private WmsWareHouseInventoryMapper wareHouseInventoryMapper;

    @Resource
    private SelectInfoMapper selectInfoMapper;

    // ==========================================================
    // 模块名称: 转库单解析模块
    // 功能描述: 解析转库单相关的业务逻辑
    // ==========================================================

    /**
     * 解析 NCC 转库单
     *
     * @param nccApiResponse NCC 返回结果
     * @return 解析结果
     */
    public List<Map<String, Object>> processTransferOrderResponse(NccApiResponse nccApiResponse,Boolean isConfirm) {

        List<Map<String, Object>> resultsMap = new ArrayList<>();
        JSONArray dataArray = nccApiResponse.getData();

        // 如果数据列表为空，则初始化为空数组
        if (dataArray == null) {
            return resultsMap;
        }

        // 遍历数据并解析
        for (int i = 0; i < dataArray.size(); i++) {
            JSONObject dataObject = dataArray.getJSONObject(i);

            // 解析订单头
            JSONObject whsTransBillHeaderVo = dataObject.getJSONObject("ic.WhsTransBillHeaderVO");
            if (whsTransBillHeaderVo == null) {
                continue; // 跳过缺少订单头的数据
            }

            Map<String, Object> whsTransBillHeader = parseWhsTransBillHeaderVo(whsTransBillHeaderVo);
            String vbillcode = (String) whsTransBillHeader.getOrDefault("vbillcode", "");
            String cspecialhid = (String) whsTransBillHeader.get("cspecialhid");
            int isExist = whstransbillMapper.selectIsExist(vbillcode);

            if (isExist > 0 && isConfirm) {
                continue;
            } else {
                whsTransBillHeader.put("isConfirm", 0);
            }

            // 获取入库仓库和出库仓库
            String toWareHousePk = extractWarehousePk(whsTransBillHeader, "cotherwhid");
            String fromWareHousePk = extractWarehousePk(whsTransBillHeader, "cwarehouseid");

            // 获取仓库移动类型
            String wareHouseType = wareHouseInventoryMapper.selectMovementType(fromWareHousePk, toWareHousePk);
            if (!"TransferWareHouseNo".equals(wareHouseType)) {
                whsTransBillHeader.put("transType", wareHouseType);
            } else {
                continue;
            }

            // 解析订单行
            JSONArray whsTransBillBodyList = dataObject.getJSONArray("ic.WhsTransBillBodyVO");
            if (whsTransBillBodyList == null || whsTransBillBodyList.isEmpty()) {
                continue; // 跳过没有订单行的数据
            }
            // 解析订单行数据
            List<Map<String, Object>> details = parseWhsTransBillBodyList(whsTransBillBodyList, vbillcode,
                    wareHouseType, cspecialhid, whsTransBillHeader.get("cotherwhid"), whsTransBillHeader.get("cwarehouseid"));

            // 包装订单头和订单行信息
            Map<String, Object> billData = new HashMap<>(2);
            billData.put("header", whsTransBillHeader);
            billData.put("details", details);

            resultsMap.add(billData);
        }

        return resultsMap;
    }

    /**
     * 提取仓库 PK。
     */
    private String extractWarehousePk(Map<String, Object> whsTransBillHeader, String key) {
        @SuppressWarnings("unchecked")
        Map<String, Object> warehouse = (Map<String, Object>) whsTransBillHeader.get(key);
        if (warehouse != null) {
            boolean isMapped = (boolean) warehouse.getOrDefault("isMap", false);
            return isMapped ? (String) warehouse.get("pk") : (String) warehouse.get("code");
        }
        return "";
    }

    /**
     * 解析订单头数据
     *
     * @param whsTransBillHeaderVO 订单头 JSON 对象
     * @return 订单头解析结果
     */
    private Map<String, Object> parseWhsTransBillHeaderVo(JSONObject whsTransBillHeaderVO) {
        // 解析订单头逻辑
        HashMap<String, Object> whsTransBillHeaderVoMap = new HashMap<>(16);

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        //vnote(备注）
        DataProcessUtils.getStringField(whsTransBillHeaderVO, "vnote", whsTransBillHeaderVoMap);

        // fbillflag(单据状态）
        DataProcessUtils.getStringField(whsTransBillHeaderVO, "fbillflag", whsTransBillHeaderVoMap);

        // cspecialhid(表头主键）
        DataProcessUtils.getStringField(whsTransBillHeaderVO, "cspecialhid", whsTransBillHeaderVoMap);

        // ctrantypeid(出入库类型）
        DataProcessUtils.getStringField(whsTransBillHeaderVO, "ctrantypeid", whsTransBillHeaderVoMap);

        // ntotalnum(总数量）
        DataProcessUtils.getFormattedDouble(whsTransBillHeaderVO, "ntotalnum", whsTransBillHeaderVoMap);

        // dmakedate（制单日期）
        DataProcessUtils.handleDateField(whsTransBillHeaderVO, "dmakedate", sdf, whsTransBillHeaderVoMap);

        // billmaker（制单人）
        DataProcessUtils.processField(whsTransBillHeaderVO, whsTransBillHeaderVoMap, "billmaker");

        // creationtime(创建时间)
        DataProcessUtils.handleDateField(whsTransBillHeaderVO, "creationtime", sdf, whsTransBillHeaderVoMap);

        // pk_org_v(库存组织）
        DataProcessUtils.processField(whsTransBillHeaderVO, whsTransBillHeaderVoMap, "pk_org_v");

        //dbilldate（单据日期）
        DataProcessUtils.handleDateField(whsTransBillHeaderVO, "dbilldate", sdf, whsTransBillHeaderVoMap);

        // 获取创建人 creator
        DataProcessUtils.processField(whsTransBillHeaderVO, whsTransBillHeaderVoMap, "creator");

        // cwarehouseid(仓库）
        DataProcessUtils.processField(whsTransBillHeaderVO, whsTransBillHeaderVoMap, "cwarehouseid");

        // vtrantypecode（出库类型编码）
        DataProcessUtils.getStringField(whsTransBillHeaderVO, "vtrantypecode", whsTransBillHeaderVoMap);

        // vbillcode（单据编号）
        DataProcessUtils.getStringField(whsTransBillHeaderVO, "vbillcode", whsTransBillHeaderVoMap);

        // cbizid（出库业务员）
        DataProcessUtils.processField(whsTransBillHeaderVO, whsTransBillHeaderVoMap, "cbizid");

        // cdptid（出库部门）
        DataProcessUtils.processField(whsTransBillHeaderVO, whsTransBillHeaderVoMap, "cdptid");

        //corpoid(公司）
        DataProcessUtils.processField(whsTransBillHeaderVO, whsTransBillHeaderVoMap, "corpoid");

        //modifier
        DataProcessUtils.processField(whsTransBillHeaderVO, whsTransBillHeaderVoMap, "modifier");

        // vadjuster(转入人）
        DataProcessUtils.processField(whsTransBillHeaderVO, whsTransBillHeaderVoMap, "vadjuster");

        // approver(审核人）
        DataProcessUtils.processField(whsTransBillHeaderVO, whsTransBillHeaderVoMap, "approver");

        // cauditorid（出库人）
        DataProcessUtils.processField(whsTransBillHeaderVO, whsTransBillHeaderVoMap, "cauditorid");

        //cdptvid(出库部门）
        DataProcessUtils.processField(whsTransBillHeaderVO, whsTransBillHeaderVoMap, "cdptvid");

        //cotherbizid（入库业务员）
        DataProcessUtils.processField(whsTransBillHeaderVO, whsTransBillHeaderVoMap, "cotherbizid");

        //cotherdptid(入库部门）
        DataProcessUtils.processField(whsTransBillHeaderVO, whsTransBillHeaderVoMap, "cotherdptid");

        // cotherwhid(入库仓库）
        DataProcessUtils.processField(whsTransBillHeaderVO, whsTransBillHeaderVoMap, "cotherwhid");

        //dshldarrivedate(应到货日期）
        DataProcessUtils.handleDateField(whsTransBillHeaderVO, "dshldarrivedate", sdf, whsTransBillHeaderVoMap);

        //dshlddiliverdate(应发货日期）
        DataProcessUtils.handleDateField(whsTransBillHeaderVO, "dshlddiliverdate", sdf, whsTransBillHeaderVoMap);

        // Vdef2(生产批号）
        DataProcessUtils.getStringField(whsTransBillHeaderVO, "vdef2", whsTransBillHeaderVoMap);

        //vdef1(成本项目）
        DataProcessUtils.processField(whsTransBillHeaderVO, whsTransBillHeaderVoMap, "vdef1");

        // vdef3(需求日期）
        DataProcessUtils.handleDateField(whsTransBillHeaderVO, "vdef3", sdf, whsTransBillHeaderVoMap);

        //cotherdptvid(入库部门）
        DataProcessUtils.processField(whsTransBillHeaderVO, whsTransBillHeaderVoMap, "cotherdptvid");

        //modifiedtime
        DataProcessUtils.handleDateField(whsTransBillHeaderVO, "modifiedtime", sdf, whsTransBillHeaderVoMap);

        //ntotalpiece（应出总数量）
        DataProcessUtils.getFormattedDouble(whsTransBillHeaderVO, "ntotalpiece", whsTransBillHeaderVoMap);


        return whsTransBillHeaderVoMap;
    }

    /**
     * 解析订单行数据列表
     *
     * @param whsTransBillBodyList 订单行 JSON 数组
     * @param vbillcode            单据编号
     * @param wareHouseType        转库类型
     * @return 订单行解析结果列表
     */
    private List<Map<String, Object>> parseWhsTransBillBodyList(JSONArray whsTransBillBodyList,
                                                                String vbillcode,
                                                                String wareHouseType,
                                                                String cspecialhid,
                                                                Object cotherwhid,
                                                                Object cwarehouseid) {
        List<Map<String, Object>> details = new ArrayList<>();
        for (int j = 0; j < whsTransBillBodyList.size(); j++) {
            JSONObject whsTransBillBody = whsTransBillBodyList.getJSONObject(j);
            Map<String, Object> bodyMap = parsingWhsTransBillBody(whsTransBillBody);
            bodyMap.put("vbillcode", vbillcode);
            bodyMap.put("transType", wareHouseType);
            bodyMap.put("cspecialhid", cspecialhid);
            bodyMap.put("cotherwhid", cotherwhid);
            bodyMap.put("cwarehouseid", cwarehouseid);
            details.add(bodyMap);
        }
        return details;
    }

    /**
     * 解析ic.WhsTransBillBodyVO
     *
     * @param jsonObject JSONObject实体类
     * @return 解析后的数据
     */
    private Map<String, Object> parsingWhsTransBillBody(JSONObject jsonObject) {
        HashMap<String, Object> whsTransBillBodyVOMap = new HashMap<>(16);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        //cspecialhid(表头主键）
        DataProcessUtils.getStringField(jsonObject, "cspecialhid", whsTransBillBodyVOMap);

        // pk_batchcode(批次主键）
        DataProcessUtils.getStringField(jsonObject, "pk_batchcode", whsTransBillBodyVOMap);

        //cspecialbid（表体主键）
        DataProcessUtils.getStringField(jsonObject, "cspecialbid", whsTransBillBodyVOMap);

        //castunitid（单位）
        DataProcessUtils.processField(jsonObject, whsTransBillBodyVOMap, "castunitid");

        //cunitid（主单位）
        DataProcessUtils.processField(jsonObject, whsTransBillBodyVOMap, "cunitid");

        //cbodywarehouseid（库存仓库）
        DataProcessUtils.processField(jsonObject, whsTransBillBodyVOMap, "cbodywarehouseid");

        //cmaterialvid(物料信息）
        DataProcessUtils.processField(jsonObject, whsTransBillBodyVOMap, "cmaterialvid");
        @SuppressWarnings("unchecked") HashMap<String, Object> pkMaterial = (HashMap<String, Object>) whsTransBillBodyVOMap.get("cmaterialvid");
        // 查询物料的其他信息（保质期管理、批次管理、保质期单位、保质期）
        String pk = pkMaterial.get("pk").toString();
        HashMap<String, Object> additionMap = wareHouseInventoryMapper.selectAdditionalManagement(pk);
        whsTransBillBodyVOMap.put("additionMap", additionMap);

        //cproductorid（生产厂商）
        DataProcessUtils.processField(jsonObject, whsTransBillBodyVOMap, "cproductorid");

        //crowno（行号）
        DataProcessUtils.getStringField(jsonObject, "crowno", whsTransBillBodyVOMap);

        // vbatchcode（批次号）
        DataProcessUtils.getStringField(jsonObject, "vbatchcode", whsTransBillBodyVOMap);

        // nnum(应转数量）
        DataProcessUtils.getFormattedDouble(jsonObject, "nnum", whsTransBillBodyVOMap);

        // cstateid(库存状态）
        DataProcessUtils.getStringField(jsonObject, "cstateid", whsTransBillBodyVOMap);

        //casscustid(客户）
        DataProcessUtils.processField(jsonObject, whsTransBillBodyVOMap, "casscustid");

        //clocationid(库位）
        DataProcessUtils.processField(jsonObject, whsTransBillBodyVOMap, "clocationid");

        //ctplcustomerid(货主客户)
        DataProcessUtils.processField(jsonObject, whsTransBillBodyVOMap, "ctplcustomerid");

        //cvendorid(供应商)
        DataProcessUtils.processField(jsonObject, whsTransBillBodyVOMap, "cvendorid");

        //cvmivenderid(寄存供应商）
        DataProcessUtils.processField(jsonObject, whsTransBillBodyVOMap, "cvmivenderid");

        //cmaterialoid
        DataProcessUtils.processField(jsonObject, whsTransBillBodyVOMap, "cmaterialoid");

        //dproductdate_148(生产日期）
        DataProcessUtils.handleDateField(jsonObject, "dproductdate_148", sdf, whsTransBillBodyVOMap);

        //vinvaliddate_148(有效期至）
        DataProcessUtils.handleDateField(jsonObject, "vinvaliddate_148", sdf, whsTransBillBodyVOMap);

        // 生产日期
        DataProcessUtils.handleDateField(jsonObject, "dproducedate", sdf, whsTransBillBodyVOMap);

        // 有效期至
        DataProcessUtils.handleDateField(jsonObject, "dvalidate", sdf, whsTransBillBodyVOMap);

        //vbcdef1(合箱说明）
        DataProcessUtils.getStringField(jsonObject, "vbcdef1", whsTransBillBodyVOMap);

        // Vbcdef2(供应商代码）
        DataProcessUtils.getStringField(jsonObject, "vbcdef2", whsTransBillBodyVOMap);

        // vbdef2(需求日期)
        DataProcessUtils.handleDateField(jsonObject, "vbdef2", sdf, whsTransBillBodyVOMap);

        //vvendbatchcode(供应商批次号)
        DataProcessUtils.getStringField(jsonObject, "vvendbatchcode", whsTransBillBodyVOMap);

        // vbatchcodenote
        DataProcessUtils.getStringField(jsonObject, "vbatchcodenote", whsTransBillBodyVOMap);

        // nvolume
        DataProcessUtils.getFormattedDouble(jsonObject, "nvolume", whsTransBillBodyVOMap);

        // nweight
        DataProcessUtils.getFormattedDouble(jsonObject, "nweight", whsTransBillBodyVOMap);

        //nassistnum
        DataProcessUtils.getFormattedDouble(jsonObject, "nassistnum", whsTransBillBodyVOMap);

        // csourcetranstype
        DataProcessUtils.getStringField(jsonObject, "csourcetranstype", whsTransBillBodyVOMap);

        // csourcetype
        DataProcessUtils.getStringField(jsonObject, "csourcetype", whsTransBillBodyVOMap);

        // vsourcebillcode
        DataProcessUtils.getStringField(jsonObject, "vsourcebillcode", whsTransBillBodyVOMap);

        // csourcebillhid
        DataProcessUtils.getStringField(jsonObject, "csourcebillhid", whsTransBillBodyVOMap);

        // csourcebillbid
        DataProcessUtils.getStringField(jsonObject, "csourcebillbid", whsTransBillBodyVOMap);

        // dproducedate
        DataProcessUtils.handleDateField(jsonObject, "dproducedate", sdf, whsTransBillBodyVOMap);

        // dvalidate
        DataProcessUtils.handleDateField(jsonObject, "dvalidate", sdf, whsTransBillBodyVOMap);

        // vbdef49
        DataProcessUtils.getStringField(jsonObject, "vbdef49", whsTransBillBodyVOMap);

        //vbdef50
        DataProcessUtils.getStringField(jsonObject, "vbdef50", whsTransBillBodyVOMap);

        // Vbcdef3(包材版本)
        DataProcessUtils.getStringField(jsonObject, "vbcdef3", whsTransBillBodyVOMap);

        //vchangerate
        DataProcessUtils.getStringField(jsonObject, "vchangerate", whsTransBillBodyVOMap);

        // vbdef1（请验数量）
        DataProcessUtils.getFormattedDouble(jsonObject, "vbdef1", whsTransBillBodyVOMap);

        // dbizdate（调整日期）
        DataProcessUtils.handleDateField(jsonObject, "dbizdate", sdf, whsTransBillBodyVOMap);

        // cmaterialvid.vapprovalnumber_148（批准文号）
        String vapprovalnumber148 = jsonObject.getString("cmaterialvid.vapprovalnumber_148");
        whsTransBillBodyVOMap.put("vapprovalnumber_148", vapprovalnumber148 == null ? "" : vapprovalnumber148);

        // cmaterialvid.vmanufacturer_148 生产厂家信息
        DataProcessUtils.processField(jsonObject, whsTransBillBodyVOMap, "cmaterialvid.vmanufacturer_148");
        if (whsTransBillBodyVOMap.get("cmaterialvid.vmanufacturer_148") != null) {
            Object vmanufacturer148 = whsTransBillBodyVOMap.get("cmaterialvid.vmanufacturer_148");
            whsTransBillBodyVOMap.remove("cmaterialvid.vmanufacturer_148");
            whsTransBillBodyVOMap.put("vmanufacturer_148", vmanufacturer148);
        }

        // cmaterialvid.cholder_148 持有人/注册人
        DataProcessUtils.processField(jsonObject, whsTransBillBodyVOMap, "cmaterialvid.cholder_148");
        if (whsTransBillBodyVOMap.get("cmaterialvid.cholder_148") != null) {
            Object cholder148 = whsTransBillBodyVOMap.get("cmaterialvid.cholder_148");
            whsTransBillBodyVOMap.remove("cmaterialvid.cholder_148");
            whsTransBillBodyVOMap.put("cholder_148", cholder148);
        }

        //vnotebody（行备注）
        DataProcessUtils.getStringField(jsonObject, "vnotebody", whsTransBillBodyVOMap);

        return whsTransBillBodyVOMap;
    }

    /**
     * 设置仓库ID
     *
     * @param nccRequestDTO 查询条件
     */
    public void setWarehouseIds(NccRequestDTO nccRequestDTO) {
        Set<String> warehouseIds = nccRequestDTO.getWarehouseid();
        Set<String> cotherwhid = nccRequestDTO.getCotherwhid();
        if (warehouseIds != null && !warehouseIds.isEmpty()) {
            for (String warehouseId : warehouseIds) {
                String warehouseCode = selectInfoMapper.getWarehouseId(warehouseId);
                warehouseIds.remove(warehouseId);
                warehouseIds.add(warehouseCode);
            }
        }

        if (cotherwhid != null && !cotherwhid.isEmpty()) {
            for (String cotherwhid1 : cotherwhid) {
                String warehouseCode = selectInfoMapper.getWarehouseId(cotherwhid1);
                cotherwhid.remove(cotherwhid1);
                cotherwhid.add(warehouseCode);
            }
        }
        nccRequestDTO.setWarehouseid(warehouseIds);
        nccRequestDTO.setCotherwhid(cotherwhid);
    }
}
